package ArithmeticLibrary.Elements;

import ArithmeticLibrary.Sets.Field;

/**
 * This class represents an element that holds a Value, and knows the set it belongs to. 
 * This class supports the operations of a field: 
 * 	addition, multiplication, power, additive inverse and multiplicative inverse.
 * 
 * @author Lea Golan
 */
public abstract class ElementField {
	
	/**
	 * Compare this to obj by checking equivalence of the value and the set.
	 */
	public abstract boolean equals(java.lang.Object obj); 
	
	/**
	 * Checks if this structure is consistent with obj structure. 
	 * The structure is as follows:
	 * 		For non product elements, it returns true iff obj is an instance of the same class. 
	 * 		For product elements, the function calls to checkStructure of every element from the array of elements it holds
	 * 
	 * @param obj an object we want to check with our structure
	 * @return true iff this and obj are of the same structure
	 */
	public abstract boolean checkStructure(java.lang.Object obj); 
	
	/**
	 * Returns the element representation number in the field.
	 * Returns null for ProductField, ProductGroup since their value is an array and not BigInteger.
	 * 
	 * @return element representation number in the field
	 */
	public abstract java.math.BigInteger getElementValue(); 
	
	/**
	 * @return the field which contains this element
	 */
	public abstract Field getField(); 
	
	/**
	 * Returns a new field element which is the result of adding the current element 
	 * to the other element (both elements should be in the same field).
	 *  
	 * @param other - the element we want to add
	 * @return a new element that is the result of adding this to other 
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementField add(ElementField other) throws Exception;
	
	/**
	 * Returns a new field element which is the result of multiplying the current element 
	 * with the other element (both elements should be in the same field).
	 * 
	 * @param other - the element we want to multiply
	 * @return a new element that is the result of multiplying this to other 
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementField multiply(ElementField other) throws Exception; 
	
	/**
	 * Returns a new field element which is the result of calculating this^exponent.
	 * 
	 * @param exponent - an exponent
	 * @return a new ElementField that holds the value this^exponent
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementField power(java.math.BigInteger exponent) throws Exception; 
	
	/**
	 * @return a new field element which is the multiplicative inverse of this
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementField multInverse() throws Exception; 
	
	/**
	 * @return a new field element which is the additive inverse of this
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementField additiveInverse() throws Exception; 
	
}

